package com.bitrate.dagger.server.mqtt.listener;

import net.dreamlu.iot.mqtt.codec.MqttCodecUtil;
import net.dreamlu.iot.mqtt.codec.MqttVersion;
import net.dreamlu.iot.mqtt.core.server.event.IMqttConnectStatusListener;
import net.dreamlu.iot.mqtt.spring.server.MqttServerTemplate;
import net.dreamlu.mica.core.utils.JsonUtil;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.tio.core.ChannelContext;
import org.tio.core.Node;

import java.util.HashMap;
import java.util.Map;

/**
 * mqtt 连接状态
 */
@Service
public class MqttConnectStatusListener implements IMqttConnectStatusListener, SmartInitializingSingleton {
	private static final Logger log = LoggerFactory.getLogger(MqttConnectStatusListener.class);

	@Autowired
	private ApplicationContext applicationContext;
	private MqttServerTemplate mqttServerTemplate;

	@Override
	public void online(ChannelContext context, String clientId, String username) {
		log.info("Mqtt clientId:{} username:{} online.", clientId, username);
		// 示例，自行实现上下线类 emqx： sys topic
		String topic = "$SYS/brokers/${node}/clients/${clientId}/connected".replace("${node}", "iothub")
				.replace("${clientId}", clientId);

		Map<String, Object> data = new HashMap<>();
		data.put("clientid", clientId);
		data.put("username", username);
		data.put("ts", System.currentTimeMillis());
		data.put("connected_at", context.stat.timeFirstConnected);
		MqttVersion mqttVersion = MqttCodecUtil.getMqttVersion(context);
		data.put("proto_name", mqttVersion.protocolName());
		data.put("proto_ver", mqttVersion.protocolLevel());
		Node clientNode = context.getClientNode();
		data.put("ipaddress", clientNode.getIp());
		data.put("sockport", clientNode.getPort());
		// 发送消息
		mqttServerTemplate.publishAll(topic, JsonUtil.toJsonAsBytes(data));
	}

	@Override
	public void offline(ChannelContext context, String clientId, String username, String reason) {
		log.info("Mqtt clientId:{} username:{} offline reason:{}.", clientId, username, reason);
		// 示例，自行实现上下线类 emqx： sys topic
		String topic = "$SYS/brokers/${node}/clients/${clientId}/disconnected".replace("${node}", "iothub")
				.replace("${clientId}", clientId);

		Map<String, Object> data = new HashMap<>();
		data.put("clientid", clientId);
		data.put("username", username);
		data.put("ts", System.currentTimeMillis());
		data.put("disconnected_at", System.currentTimeMillis());
		MqttVersion mqttVersion = MqttCodecUtil.getMqttVersion(context);
		data.put("proto_name", mqttVersion.protocolName());
		data.put("proto_ver", mqttVersion.protocolLevel());
		Node clientNode = context.getClientNode();
		data.put("ipaddress", clientNode.getIp());
		data.put("sockport", clientNode.getPort());
		data.put("reason", reason);
		// 发送消息
		mqttServerTemplate.publishAll(topic, JsonUtil.toJsonAsBytes(data));
	}

	public void afterSingletonsInstantiated() {
		mqttServerTemplate = applicationContext.getBean(MqttServerTemplate.class);
	}
}
